﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace XDL.Framework.Particles
{
    public class TrailEmitter
    {
        ParticleSystem m_particleSystem;
        float m_timeBetweenParticles;
        /// <summary>
        /// Constructs a new particle emitter object.
        /// </summary>
        public TrailEmitter(ParticleSystem particleSystem,
                               float particlesPerSecond)
        {
            m_particleSystem = particleSystem;
            m_timeBetweenParticles = 1.0f / particlesPerSecond;
        }

        /// <summary>
        /// Returns the underlying <see cref="ParticleSystem"/> instance.
        /// </summary>
        public ParticleSystem ParticleSystem
        {
            get { return m_particleSystem; }
        }

        /// <summary>
        /// Updates the emitter, creating the appropriate number of particles
        /// in the appropriate positions.
        /// </summary>
        /// <param name="gameTime">Current game time</param>
        /// <param name="newPosition">New emitter position</param>
        /// <param name="velocity">New initial velocity</param>
        public void Update(GameTime gameTime, ParticleVertex oldParticle, ParticleVertex currentParticle)
        {
            // Work out how much time has passed since the previous update.
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (elapsedTime > 0)
            {
                // If we had any time left over that we didn't use during the
                // previous update, add that to the current elapsed time.
                float timeToSpend = currentParticle.Tag + elapsedTime;

                // Counter for looping over the time interval.
                float currentTime = -currentParticle.Tag;

                // Create particles as long as we have a big enough time interval.
                while (timeToSpend > m_timeBetweenParticles)
                {
                    currentTime += m_timeBetweenParticles;
                    timeToSpend -= m_timeBetweenParticles;

                    // Work out the optimal position for this particle. This will produce
                    // evenly spaced particles regardless of the object speed, particle
                    // creation frequency, or game update rate.
                    float mu = currentTime / elapsedTime;

                    Vector3 position = Vector3.Lerp(oldParticle.Position, currentParticle.Position, mu);
                    Vector3 velocity = Vector3.Lerp(oldParticle.Velocity, currentParticle.Velocity, mu);

                    m_particleSystem.AddParticle(position, velocity);
                }

                // Store any time we didn't use, so it can be part of the next update.
                currentParticle.Tag = timeToSpend;
            }
        }
    }
}
